package echecs;

import iechecs.type.Liste;

public class Regle1 {

    private Case c;
    private Regle1 R;
    private APiece p,  piece_candidate;
    private Position position;
    private Liste<Coups> ListeCoups;
    private Direction d = Direction.Init;
    private Direction dC = Direction.Cavalier;
    private Direction fC = Direction.FinCavalier;
    private Direction f = Direction.Fin;

    public Regle1(Case c, APiece p) {
        super();
        this.p = p;
        position = p.gen.getPosition();
        ListeCoups = p.gen.getListecoups();
        this.c = c;

    }

    public boolean P1() {
        return p.regletype.isTypeCavalier();
    }

    public boolean P2(Direction d1, Direction d2) {
        return !d1.equals(d2);
    }

    public void direction(Direction dir) {

        c = c.plus(dir);
        if (!c.equals(Case.HorsEchquier)) {
            if (position.isCaseVide(c)) {
//            if (ChessPredicat.estUneCaseVide.eval(this)) {
                ListeCoups.add(new Coups(p, p._case, c));
                if (p.regletype.isTypeNCaseDTF()) {
                    direction(dir);
                }

            } else {
                piece_candidate = position.getPiece(c);
                if (p.estCouleurInverse(piece_candidate)) {
                    if (p.regletype.isTypeRoi()) {
                        if (!isEchec()) {
                            ListeCoups.add(new Coups(p, p._case,
                                    c));
                        }
                    } else {
                        ListeCoups.add(new Coups(p, p._case,
                                c));
                    }
                }
            }
        }
    }

    public void s() {
        d = d.next();
    }

    public void sC() {
        dC = dC.next();
    }

    public boolean n(Direction dir) {
        R = new Regle1(c, p);
        R.direction(dir);
        next_dir();
        return true;
    }

    public boolean fclos() {
//        final FoncteurBinaire<Direction, Direction, Boolean> FP2 = new FoncteurBinaire<Direction, Direction, Boolean>() {
//
//            @Override
//            public Boolean fn(Direction d1, Direction d2) {
//                return !d1.equals(d2);
//            }
//        };
//        AGenerateur<Option> S = new AGenerateur<Option>() {
//
//            @Override
//            public Option gen() {
//                d = d.next();
//                return Option.NONE;
//            }
//        };
//        S.gen();
//        AGenerateur<Boolean> IF = new AGenerateur<Boolean>() {
//
//            @Override
//            public Boolean gen() {
//                return FP2.fn(d, f);
////                return P2(d, f);
//            }
//        };
//
//        AGenerateur<Boolean> TRUE = new AGenerateur<Boolean>() {
//
//            @Override
//            public Boolean gen() {
//                n(d);
//                return true;
//            }
//        };
//
//        AGenerateur<Boolean> FALSE = new AGenerateur<Boolean>() {
//
//            @Override
//            public Boolean gen() {
//                return true;
//            }
//        };
//        GenerateurConditionnel<Boolean> PourChaqueDirection = new GenerateurConditionnel<Boolean>(IF,
//                TRUE, FALSE);
//        return PourChaqueDirection.gen();
        s();
        return P2(d, f) ? n(d) : true;
//        if (P2(d, f)) {
//            n(d);
//        }
//        return true;
    }

    public boolean tclos() {
        sC();
        return P2(dC, fC) ? n(dC) : true;
//        if (P2(dC, fC)) {
//            n(dC);
//        }
//        return true;
    }

    public boolean next_dir() {
        return P1() ? tclos() : fclos();

//        if (P1()) {
//            tclos();
//
//        } else {
//            fclos();
//        }

    }

    public boolean isEchec() {
        return false;
    }

    public Case getCase_courante() {
        return c;
    }

    public Position getPosition() {
        return position;
    }
}
